package com.base.context;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;


/**
 * @author mzl
 * @desc
 */
public class ContextHolder {

    private static final Map<String, Context> CTX_REPO = new HashMap<>();
    private static       ThreadLocal<Context> tl       = new ThreadLocal<Context>();

    private ContextHolder() {
        super();
    }

    public static void appendContext(final Context context) {
        CTX_REPO.put(context.currentToken(), context);
    }

    public static Context currentContext() {
        return tl.get();
    }

    public static void bindContext(final Context context) {
        tl.set(context);
    }

    public static void unbindContext() {
        tl.remove();
    }

    public static Context contextOf(final String token) {
        return CTX_REPO.get(token);
    }

    public static void remove(final String token) {
        CTX_REPO.remove(token);
    }

    public static Context isOnline(final IUser user, Class<? extends IUser> clazz) {
        Integer tid = user.getId();
        Optional<Context> opt = CTX_REPO.entrySet().stream().map(e -> e.getValue())
                .filter(c -> null != c && null != c.currentUser() && null != c.currentUser().getId())
                .filter(c -> clazz.isAssignableFrom(c.currentUser().getClass()))
                .filter(c -> Long.compare(c.currentUser().getId(), tid) == 0)
                .findFirst();
        //
        return opt.isPresent() ? opt.get() : null;
    }

    public static Map<String, Context> contexts() {
        return new HashMap<>(CTX_REPO);
    }

    public static Context mockContext(IUser user) {
        return new ContextImpl("mock_context", user);
    }
}
